Quick Tutorial of Linux and Workstation


Posted by a113062130630210 on 2022-06-20

UNIX是一種多用戶、多工的作業系統,提供不同的使用者能夠同時在一台主機上進行各種項目服務。Linux是建構在UNIX上開發出來的核心,Ubuntu是以Linux為核心所發行的一套作業系統
可以想成UNIX是猩猩,Linux是演化後的智人(兩者能力不相同,有上下關係),而Ubuntu是白種人,Debian是黃種人,Redhat是黑種人(有相同基本能力,但是用不一樣的外觀或套件服務)
Application > Shell > Kernal
kernal: 核心,作業系統的最底層,負責和硬體溝通和真正執行我們的指令(更改記憶體,跟螢幕說要印出什麼東西)
shell: 負責將我們的輸入(也就是指令)轉換成kernal看得懂的語言,ex: gcc,ls,chmod
application:將這些指令包裝成一般的應用程式,如各種軟體、app,都是由一連串的指令或程式碼轉換成人容易操作的圖形界面

Workstation

系上的工作站大多使用Linux發行版之一的Debian,只要有電腦和網路,就能透過ssh連上工作站。SSH(Secure Shell Protocol),是一種安全的網路協定,提供我們遠端連到伺服器的服務

如何連到工作站

在Windows的cmd或是Mac/Ubuntu的terminal輸入
$ ssh <account>@<IP address>
比方說要連到meow1的話就是
$ ssh b09901133@meow1.csie.ntu.edu.tw$ ssh b09901133@meow1.csie.org
當然也可以更改ssh config,這樣的話只要打
$ ssh meow1就能連上去了,或是寫一個shell script執行ssh的指令,這樣就不用每次連工作站都打一長串了

ssh key

注意到每次連工作站都要打密碼,如果不想打密碼的話可以按照以下步驟:
1.$ ssh-keygen生成ssh key
2.之後terminal會跳出Enter file in which to save the key (~/.ssh/id_rsa)問你key要存在哪裡,直接按enter會存在預設的位置
3.Enter passphrase (empty for no passphrase):如果輸入的話,之後登入就要輸入passphrase,直接enter,就不用輸入
4.$ ssh-copy-id <account>@<IP address>並且輸入你的密碼確認,這樣之後就可以用ssh key登入了

登出工作站的話,輸入$ exit$ logout即可

Linux檔案路徑

~: home,家目錄,也就是登入系統後進入的目錄
/: root directory,根目錄,所有目錄的開始
.: working directory,當前目錄
..: parent directory,上一層

對於一個檔案系統,只有一個根目錄,對於一個使用者,只有一個家目錄(ex: b09901133的家目錄是/home/student/09/b09901133)

絕對路徑: 以/開頭,表示從根目錄開始
相對路徑: 以./開頭,表示從當前目錄開始,而一般如果不寫的話就是預設從./開始

以下介紹幾個常見的目錄
/bin: 可執行檔
/dev: 週邊設備
/lib: 函式庫
/etc: 系統設定
/home: 家目錄
/usr: 軟體資源
/tmp: 暫存檔
/var: 動態數據

以下介紹幾個常用的指令
pwd: print working directory,印出現在所在的目錄
ls: list,列出本目錄
常用參數有:

  • -a(all) 列出包含隱藏檔案的所有檔案(隱藏檔案檔名開頭會有.)
  • -l(long listing) 用清單格式列出,可以看到檔案的權限、時間戳、檔名、大小
  • -t(time) 依照最後編輯時間列出
  • -h(human readable) 用好讀的方式印出
    $ ls dir/     列出./dir下的所有檔案
    $ ls -al      列出當前目錄的所有檔案,用清單方式列出,包含隱藏檔
    
    cd: change directory,前往指定的目錄
    $ cd   回到家目錄
    $ cd ~ 回到家目錄
    $ cd /home/student/10 到/home/student/10這個目錄
    $ cd .. 到上一層目錄
    $ cd / 到根目錄
    

上傳/下載檔案

sftp
ssh file transfer protocol
$ sftp b09901133@linux1.csie.ntu.edu.tw
登入之後:

$ get <remote-path> [local-path] 從remote-path下載到local-path
$ put <local-path> [remote-path] 從local-path上傳到remote-path
$ cd 移動遠端路徑
$ ls 查看遠端資料

如果要上傳或下載整個目錄的話,要加上-r

wget <URL>
World Wide Web get
$ wget http:example.com
$ wget -O hi.html http:example.com 下載檔案,檔名為hi.html
$ wget -O - http:example.com 下載檔案,並且當作文字檔案輸出到terminal
相似的指令有curl,預設是把檔案內容直接輸出到terminal:
$ curl <url> 產生的結果類似 $wget -O - <url>

Terminal小技巧

tab鍵

按tab可以自動補足指令或目錄或檔案名稱,但是遇到多個可能會停在分岔點,連按兩次可以列出所有可能性

上下鍵

可以回到上一個指令/下一個指令

萬用字元(*)

代表零或不限個數個任何字元
ex: abc.caabbcc都是*c

複製/貼上/刪除

在terminal中,複製是 ctrl+shift+C,貼上是ctrl+shift+V,刪除的話是ctrl+W(刪除一個字)和ctrl+U(整行刪除)

clear: 清空目前畫面
ctrl+C: 中止目前程式
ctrl+D: 在stdin中代表EOF,windows中則是ctrl+Z
exit: 離開terminal,包括ssh連上工作站或是sftp連上工作站或是自己開一個terminal的時候都可以這樣離開terminal
alias: 設定或印出指令的別名,如果自己想要個人化一些指令的話可以使用這個

$ alias ll 告訴你執行ll的時候實際上執行什麼
$ alias md="mkdir -p" 設定執行md是執行mkdir -p

cheat.sh: 用$ curl cheat.sh/<command name>可以看到command的常見用法,個人認為比man好用一點
man <command name>: manual,可以看到指令的詳細用法

檔案管理與操作

cp: copy,複製檔案,被複製的在前,複製出的在後,可以用路徑指定複製出的東西的位置,要複製整個目錄要-r

$ cp <file1> <file2> 在當前目錄將file1另存新檔為file2
$ cp <file> dir/ 將file複製到某個目錄當中
$ cp -r dir1/ dir2/ 將dir1內的所有東西複製到dir2

mv: move,移動或重新命名一個檔案或目錄

$ mv dir1/ dir2/ 如果dir2不存在就將dir1重新命名為dir2,否則將整個dir1移動到dir2裡面
$ mv <file1> dir1/ 將檔案file移動到目錄dir裡面
$ mv <file1> <file2> 將檔案file1重新命名為file2

rm: remove,永久移除檔案
常用參數:

  • -r: 遞迴的移除某個目錄以及其底下的所有檔案目錄
  • -f: 強制移除,系統不會一一詢問(預設是系統會一一詢問是否要移除掉這個檔案)
  • -d: 移除掉空的目錄
    $ rm <file> 將file移除
    $ rm -f *.c 將當前目錄以.c為結尾的所有檔案移除
    $ rm -rf dir/ 將dir目錄下所有檔案移除
    $ rm -rf * 將當前目錄所有檔案移除
    
    mkdir: make directory,建立新目錄
    常用參數
  • -p: (parent),如果需要的話,將parent directory一起新增
    $ mkdir dir/ 新增dir目錄 
    $ mkdir -p dir1/ dir2/ 在dir1裡新增dir2目錄,如果dir1不存在,就順便新增dir1
    
    rmdir: 刪除空的目錄,跟$ rm -d一樣
    touch: 點擊/戳一個檔案,如果不存在的話就建立它,可以用來改變時間戳
    $ touch <file> 新增file,或是改變file的時間戳

檔案與目錄權限

因為Linux是一個多人、多工的作業系統,因此對於一個檔案或目錄,需要去規定不同使用者知簽的權限。而在Unix-Like的作業系統中,我們會將一個檔案/目錄的權限針對擁有者(user)、同群組使用者(group)、和其他用戶(group)分為以下三種:

r(read),讀取檔案,讀取目錄內部的檔案條目(ls)
w(write),修改檔案,修改目錄屬性(ex: 名稱),並新增、刪除、更名目錄內的檔案
x(execute),執行檔案,進入該目錄內部(cd)

chmod: change mode,改變檔案/目錄的權限

$ chmod [ugo][+-][rwx] <file|dir/> 通式: 將[人]對file|dir [增減] [某權限]
$ chmod +rw <file> 將全部人對file新增讀寫權
$ chmod u+x <file> 新增自己對file的執行權
$ chmod go-r <file> 移除同群組和其他人對file的讀取權
將rwx想成二進位,r = 4, w = 2, x = 1,沒有該權限為0
$ chmod 700 dir/ 目錄權限: drwx------,d代表這是一個directory
$ chmod 644 <file> 檔案權限: -rw-r--r--,因為不是一個directory,所以沒有d這個參數

find [path] [option] [expression]
搜尋指令,只是要花比較久的時間,可以依照權限、擁有者、群組、檔案類型、日期與大小等條件來搜尋
常用參數:

  • -name: 指定檔名搜尋
  • -perm <mode>: 搜尋檔案權限為mode的檔案
  • -exec <command>: 將搜尋出的結果,使用其他指令再處理
    $ find ~ -name lost 在~下搜尋lost,預設為當前目錄
    $ find -perm 777 -exec chmod 755 {} + 將權限為777的檔案都設為755
    

本地相關指令

passwd: password,變更密碼,一般是可以用GUI設密碼的,但如果沒有GUI的話,這個指令其實還不錯好
sudo: superdoer,以superuser的權限執行指令,在工作站上不能用,有些跟安全性或系統內部的指令需要有superdoer的權限才能進行動作

$ sudo apt-get install vim 安裝vim
#apt-get是一個安裝套件的指令

工作管理

process簡介
process是程序,又稱行程、進程,是執行中的程式,每個程序會有一些屬性:

  • PID 程序獨特的識別碼
  • UID 產生這個程序的使用者
  • NICE 一個程序的友好程度,介在-20跟19之間,值越大,代表這個程序的執行優先度越低,越不會跟別人搶系統資源

ps: process status,查看程序的狀態
常用參數:

  • -l: 詳細列出程序的資訊
  • aux: 查看系統上的所有程序
    $ ps -l
    $ ps aux
    

kill: 可以結束指定PID的程序
常用參數:

  • -9: 強制結束
    $ kill 204 結束pid為204的程序

htop: 圖形化界面的程序管理員,可以查看執行中的程序,系統資源用量

CPU

htop最上方會列出各CPU的使用率,這邊顯示的是CPU的邏輯核心數(我也看不懂),譬如電腦有四核心八執行緒,意思是可以同時執行八個thread,那這邊就會顯示八個CPU

而這個使用率的bar會有三種顏色,每個顏色有各自代表的意義

  • 紅色: 代表kernal thread佔用的CPU,像是系統需要自動做process scheduling、memory management等等,是系統中最重要、優先權最高的任務
  • 綠色: 代表normal priority thread,優先度比kernal thread低,一般使用者的程式沒有特別調優先權的話,會被歸在這一類
  • 藍色: 代表low priority thread,優先權比較低,分配到的CPU也比較少,如果CPU很滿或是memory真的不夠用了,第一個kill掉的也是這類程序

Memory & Swp

它的顏色也是有意義的

  • 綠色: 被process佔用的記憶體,比方說瀏覽器、terminal、htop
  • 藍色: buffer pages,譬如說當你第一次ls -l的時候系統會去硬碟撈這個資料夾有哪些檔案、每個檔案的權限,然後存在buffer pages,這樣短時間再ls -l的時候就不用再進入硬碟(因為進入硬碟比較慢),直接從buffer拿即可
  • 橘色: cache pages,跟buffer很像,只不過buffer存metadata,cache存檔案內容,像第一次下cat index.js就會把內容讀取到cache pages,如果cat之後發現檔案太長,只要看前十行就好,那再下head -n 10 index.js就會從cache pages直接讀取

記憶體使用量並非越低越好,畢竟閒在那邊也沒什麼用,不如讓系統把閒置的部份拿去當buffer跟cache,這樣就可以盡量不碰硬碟,執行速度更快

swap的機制跟buffer還有cache相反,如果memory快不夠了,系統會把記憶體裡面一些東西swap到硬碟上,等真的需要再拿回來,缺點是程式速度會比較慢

Load Average

首先Tasks欄位的488, 1994 thr; 3 running代表目前總共有488個process、1994個thread,其中3個thread正在執行
Load Average是用來判斷目前系統有多忙,三個數字代表系統在最近一分鐘、五分鐘、十五分鐘內,平均有多少個thread需要CPU

PID/USER

PID是每個process的ID,可以用kill -KILL <pid>來殺掉某個process,或用kill -STOP來暫停process然後用kill -CONT讓它繼續執行
USER就是把這個process跑起來的人,不管程式是誰寫的,只要是我把它跑起來,USER就會顯示我的名字

PRI & NI

Priority跟Nice都是跟優先權有關的指標,注意數字越小表示優先權越高,可以分配到更多CPU,PRI是由系統決定的,無法自行更改,Nice預設是0,可以用renice -n 19 -p <pid>調整到最低優先權19,調高的話最高可以調到-20

雖然nice值可以自行調整,但系統不一定會根據nice來分配優先權,有些完全只根據PRI系統根本不在乎Nice

VIRT/RES/SHR

Virtual Memory,Resident,Shared Memory

Virtual Memory可以把它想成process可以存取到的memory總和,譬如說head -n index.js運作的方式就是把index.js打開,然後讀取前十行,雖然只讀取前十行,但head process已經把檔案打開了,它其實有權限access到整個檔案,所以virtual memory會把整個檔案的大小算進去

Resident是物理上佔用了多少記憶體,如果只讀取前十行,那系統就只把前十行從硬碟讀進記憶體,Resident也只算那十行

因此在htop裡Resident一定遠小於Virtual Memory

Shared Memory是可以跟別人分享的memory,像程式時常用的glibc,或是在讀取read-only檔案時,這些東西只要讀進記憶體一次就好了,所以會被算進SHM裡面

State

  • R: process正在跑或是在running queue裡等待CPU排程
  • S: 目前正在睡覺,有事做才會醒來
  • D: 這個也是在睡覺,只不過等待的一定是IO,譬如說讀取檔案、寫入資料庫等等

CPU%/MEM%

CPU%意思是在這段時間平均用了幾顆CPU,因為htop預設3秒更新一次,假如前1.5秒用了一顆,後1.5都沒用,那平均就是50%,如果這3秒用好用滿四個核心,那就是400%

因為CPU%是很短期的數據,所以當電腦當當的時候,看CPU%就可以知道是誰在霸佔CPU

MEM%也很類似,是使用記憶體的比例,並且使用Resident來計算,所以如電腦配有4GB的記憶體,某個process的Resident是1GB,那就是用掉實體記憶體的25%

Time+

代表的並不是程式從啟動到現在總共經過了多久,而是這個程式總共佔用了多少CPU Time

因此如果想知道長期而言哪個程式最佔CPU的話,就看Time+的數值,如果是看短期、目前正在暴衝的程式,就看之前提到的CPU%

常用參數:

  • -u 只顯示特定使用者的程序
  • -p 只顯示特定的程序
  • -s 將程序按照特定資訊欄排序
$ htop -u b09901133 查看b09901133的程序資訊
$ htop -s USER 將程序照使用者排序

ctrl+Z: 暫停目前的程序

jobs: 列出目前terminal中的程序,包含在背景執行或暫停的
$ jobs -l 列出這個terminal裡面的程序,並且附上PID

文字/輸出處理

cat: Concatenate,串接並輸出一個以上的檔案的內容。參數-n可以在每一行加上行號

$ cat <file1> <file2> <file3> 串接file1、file2、和file3輸出
$ cat -n <file> 將file每行前都加入行號輸出
$ cat *.c 將所有.c檔都串接在一起輸出

less: 跟cat類似,不過比較像是閱讀器的功能,可以一頁一頁讀(空白鍵)或是一行一行讀(上下鍵),可以按q離開或是/?搜尋

head / tail: 顯示檔案的前面幾行或最後幾行,預設是10行,可以用-n num-num指定行數

$ head *.c -n 5 顯示檔案結尾為.c的前5行
$ tail file[1-5] -13 顯示file1-file5的末13行

wc: word count,計算一個檔案內的行數(line)/字數(word)/字元數(char),不加參數就是分別顯示以上三者,如果加上一個以上的參數則輸出指定的內容

$ wc <file> 顯示三種資訊(line/word/char)
$ wc -l <file> 顯示行數
$ wc -wc <file> 顯示字數與字元數

管線命令 pipeline

對於每個參數,都會有一個標準輸入(STDIN)、標準輸出(STDOUT)、標準錯誤輸出(STDERR),代表的數字分別是0,1,2

redirect: output(>, >>), pipe(|), input(<)
> 把STDOUT(如指令、程式結果)寫入新檔案(如果檔案名稱已經存在就覆蓋)
>& 把STDOUT+STDERR寫入新檔案(如果檔案名稱已經存在就覆蓋)
2> 把STDERR寫到檔案(如果檔案名稱已經存在就覆蓋)
>> 把STDOUT結果接續在檔案的尾端(如果檔案不存在就建立)

$ ./a.out > hello
$ ./a.out >> hello

| 管線字元可以將左邊指令或程式的輸出(stdout)變成右邊指令的輸入(stdin) 可以很方便的將不同指令寫在同一行

$ ./a.out | less

注意這個跟>不同的地方在於>是將output寫到檔案,而|則是將output當作另一個指令的stdin
兩者左邊都是接受一個指令或程式,但>右邊一定是檔案,|右邊則是另一個指令或程式

< 相較於>是把右邊檔案當作左邊指令的標準輸出(stdout),<則是把右邊檔案當作左邊指令的標準輸入(stdin),兩者可以連用

$ ./a.out < input > output

echo: 輸出文字,不搭配重導向使用就會直接輸出到stdout

$ echo Welcome to Foresight Camp 2021 \OWO/
$ echo hello judgegirl > hello
$ echo hello world >> hello

diff: difference,比較兩個檔案不同的地方,如果前面有pipe的話可以把一個設成-代表該檔案

$ diff sample_output my_output
$ ./a.out | diff sample_output -
$ diff < (./a.out < in.txt) out.txt

sort: 將檔案內容以行為單位根據字典序排序並輸出(不會更改檔案本身)
常用參數:

  • -r: reverse,反向排序
  • -f fold lower case to upper case,忽略大小寫差異
  • -n numerical value,按照數值大小排序
$ sort data
$ sort data > sorted_data

uniq: unique,以行為單位,將檔案中相鄰且重複的內容刪除到只剩一行並輸出(例如有連續五行內容完全一樣,就把四行刪掉),並不會更改檔案本身,常搭配sort使用
常用參數:

  • -c: count,進行計數
  • -i: ignore case,忽略大小寫差異
  • -u: unique,只輸出完全沒有相鄰重複的
$ sort data | uniq > unique_file
$ sort data | uniq -u > uniq_file

簡易正規表達式(Regular Exxpression, Regex)

主要是拿來match一個字串有沒有符合特定規則
*: 前面的字出現任意次數(包含0次)
+: 前面的字出現一次以上
?: 前面的字出現0次或1次
.: 一個任意字元
\: 跳脫字元,把接在後面的字當作一般字元使用
[]: 代表任一括號內的字元
^: 代表字串的開始位置
$: 代表字串的結束位置

ex:
AC\.c AC.c (前後還可以加東西)
AC?\.c AC.c以及A.c (前後還可以加東西)
AC*\.c A.c, AC.c, ACC.c ... (前後還可以加東西)
AC[1-3]\.c AC1.c、AC2.c、AC3.c (前後還可以加東西)
^AC\.c AC.c AC.cpp AC.csv ... (後面還可以加東西)
AC\.c$ AC.c, AAC.c, BAC.c ... (前面還可以加東西)
AC_.*\.c .* 可以是任何內容,可以代表AC_123.c, AC_ac.c等等

Shell中的萬用字元*在正規表達式中相當於.*,也就是任意字元出現任意次數的意思

grep: global regular expression print,從檔案中(沒有檔案就是stdin)找出符合指定字串的那些行並輸出,字串可以不用加引號,或是用regex的語法加引號(只是記得加上-E)

$ grep A+ student_grades | wc -l 從student_grades中計算A+的人數 
$ grep B10902* workstation_usage | sort | unique -c 從workstation_usage中,找出B10的使用者,在排序後輸出每人使用次數
$ ls -l /nfs/undergrad/10 | grep -E "^d[rwx]r" 看家目錄有開可以讀的權限的B10

sed: stream editor,文字串流編輯器,語法是s/origin/replace/g,一個斜線都不能少(s代表substitute,g代表global,不加g代表取代遇到的第一個origin)

$ cat letter > sed 's/love/hate/g' 把love用hate取代
$ car spaces > sed 's/^ *//g' 去除行首空白

壓縮/解壓縮

  • zip 檔
  • 加上 -e代表加密壓縮
    $ zip -r <name.zip> dir/ -r 把dir裡面所有檔案壓縮成name.zip
    $ unzip <name.zip> -d dir/ 把name.zip的檔案解壓丟到dir
    $ zip -r 2021.zip 2021_code/ -r -e
    $ unzip 2021.zip
    
  • tar 檔: 只有打包,沒有壓縮
    $ tar cvf <FileName.tar> dir/ 打包
    $ tar xvf <FileName.tar> 解包
    
  • tar.gz 檔
    $ tar zcvf <FileName.tar.gz> dir/ 壓縮
    $ tar zxvf <FileName.tar.gz> 解壓縮
    

gcc: GNU Compiler Collection,Unix-like作業系統的標準編譯器,在工作站上寫C的程式可以用gcc將原始碼編譯成執行檔
常用參數:

  • -o name: 自訂執行檔名字 預設為a.out
  • -g 讓產生的執行檔可以用GDB debug
  • -Dxxx 可以定義程式裡的xxx(關鍵字: ifdef endif)
  • -O[n] 可以做出不同等級的優化,n = 0 ~ 3, 常用是-O2
  • -Wall 顯示所有警告訊息(沒有初始化的變數、重複宣告的變數、沒被使用的變數等等),debug比較容易知道錯在理
  • -std=c99 等號後面為指定編譯器標準
$ gcc 12345.c
$ gcc problemA.c -o AA -O2 -Wall -std=c11
$ gcc defpractice.c -Ddef

執行檔案

在Linux系統,對於檔案或目錄名稱沒有特殊要求,所以不用像在Windows終需要.exe副檔名代表它的檔案格式,如果想要執行名為filename的檔案,只要在前面打./即可
$ ./filename
可執行的檔案在用ls列出時,檔名會呈現綠色且檔名後面顯示*

time: 替某個指令/程式計時,會有三種時間(real/user/sys),評估程式效率是看user time,real time可能因為工作站忙碌而被拉長

  • real time: 程式從執行開始到執行結束在錶上相差的時間
  • user time: 程式碼不需要消耗系統資源的部份所使用的CPU時間
  • system time: 程式碼需要消耗系統資源的部份所使用的CPU時間
  • user time + system time: 不一定會小於/等於/大於real time
$ time wc problem[1-9].c
$ time ./a.out < sample_input

make: 搭配makefile使用

$ make
$ make clear

tmux: 終端機的多工器,可以同時跑好幾個程式,也可以把程式丟到背景跑,輸入tmux就可以開始使用了,如果tmux不用了,exit即可,否則ctrl+B+D可以回到原本的terminal
常用的有:
tmux ls 看現在有哪幾個在跑
tmux attach -t x 其中x是session編號,可以直接進去那個session,而attach可以直接打a就好










Related Posts

Terms of Use 會員服務條款

Terms of Use 會員服務條款

Function component vs Class component

Function component vs Class component

SQL Excel Concatenate into INSERT Command

SQL Excel Concatenate into INSERT Command


Comments